﻿using AutoMapper;
using Modules.CheckIn;
using Modules.Corp;
using Modules.Person;
using Modules.Project;
using PmSoft;
using PmSoft.Utilities;

namespace ManagementApi.Models.Manage.ProjectGroupMember;

/// <summary>
/// 班组成员分页返回对象
/// </summary>
public class ProjectGroupMemberDto
{
    /// <summary>
    /// ID
    ///</summary>
    public int? Id { get; set; }

    /// <summary>
    /// 参建单位Id
    /// </summary>
    public int? CorpId { get; set; }

    /// <summary>
    /// 班组名称
    ///</summary>
    public string GroupName { get; set; }

    /// <summary>
    /// 班组Id
    /// </summary>
    public int? GroupId { get; set; }

    /// <summary>
    /// 人员Id
    /// </summary>
    public int? PersonId { get; set; }

    /// <summary>
    /// 人员名称
    ///</summary>
    public string PersonName { get; set; }

    /// <summary>
    /// 身份证号
    /// </summary>
    public string CardNumber { get; set; }

    /// <summary>
    /// 手机号码
    /// </summary>
    public string Mobile { get; set; }

    /// <summary>
    /// 当前工种
    /// </summary>
    public string TypeName { get; set; }

    /// <summary>
    /// 是否班组长
    /// </summary>
    public bool IsLeader { get; set; }

    /// <summary>
    /// 是否现场管理人员
    /// </summary>
    public bool IsManager { get; set; }

    /// <summary>
    /// 开始工作日期
    /// </summary>
    public DateTime? WorkDate { get; set; }

    /// <summary>
    /// 创建时间
    /// </summary>
    public DateTime? CreateTime { get; set; }

    /// <summary>
    /// 发卡时间
    ///</summary>
    public DateTime? IssueCardDate { get; set; }

    /// <summary>
    /// 人员状态
    ///</summary>
    public int? Status { get; set; }

    /// <summary>
    /// 人员状态名称
    ///</summary>
    public string? StatusName { get; set; }

    /// <summary>
    /// 进场时间
    /// </summary>
    public DateTime? StartDate { get; set; }

    /// <summary>
    /// 出场时间
    /// </summary>
    public DateTime? EndDate { get; set; }

    /// <summary>
    /// 是否签订合同
    /// </summary>
    public bool? HasContract { get; set; }

    public string ProjectName { get; set; }

    /// <summary>
    /// 人员工资卡号
    /// </summary>
    public string BankCardNo { get; set; }

    /// <summary>
    /// 开户银行名称
    /// </summary>
    public string BankName { get; set; }

    public int ProjectId { get; set; }

    public string CorpName { get; set; }

    /// <summary>
    /// 身份证号加密处理
    /// </summary>
    /// <returns></returns>
    public string CardNumberConvert()
    {
        return CardNumber.Substring(0, 4) + "******" + CardNumber.Substring(14);
    }

    public string MobileConvert()
    {
        return Mobile.Substring(0, 4) + "******" + Mobile.Substring(7);
    }

    /*扩展属性*/

    /// <summary>
    /// 考勤日统计
    /// </summary>
    public IEnumerable<int> CheckInDays { get; set; }

    /// <summary>
    /// 工时
    /// </summary>
    public decimal WorkHours { get; set; }

    /// <summary>
    /// 考勤天数
    /// </summary>
    public int CheckinDay { get; set; }

    /// <summary>
    /// 岗位类别
    /// </summary>
    public string PostCategoryName { get; set; }
}

public static partial class ProjectGroupMemberExceptions
{
    public static ProjectGroupMemberDto AsProjectGroupMemberDto(this Modules.Project.Entitys.ProjectGroupMember projectGroupMember)
    {
        ProjectGroupMemberDto projectGroupMemberDto = new ProjectGroupMemberDto();
        var mapper = ServiceAccessor.GetService<IMapper>();
        mapper.Map(projectGroupMember, projectGroupMemberDto);
        projectGroupMemberDto.PostCategoryName = projectGroupMember.PostCategory?.GetDescription() ?? "";

        var corpService = ServiceAccessor.GetService<CorpService>();
        var corp = corpService.GetCorpInfo(projectGroupMember.CorpId);
        if (corp != null) projectGroupMemberDto.CorpName = corp.Name;

        var projectGroupService = ServiceAccessor.GetService<ProjectGroupService>();
        var projectGroup = projectGroupService.GetProjectGroup(projectGroupMember.GroupId);

        var projectService = ServiceAccessor.GetService<ProjectService>();
        ProjectInfo? projectInfo = projectService.GetProjectInfo(projectGroupMember.ProjectId);
        if (projectInfo != null)
            projectGroupMemberDto.ProjectName = projectInfo.Name;

        if (projectGroup != null)
            projectGroupMemberDto.GroupName = projectGroup.Name;
        else projectGroupMemberDto.GroupName = "";

        var personService = ServiceAccessor.GetService<PersonService>();
        var person = personService.GetPerson(projectGroupMember.PersonId);

        var personContractService = ServiceAccessor.GetService<PersonCorpContractService>();
        var personCorpContracts = personContractService.GetPersonCorpContractsByProjectIdAndCorpIdPersonId(projectGroupMember.ProjectId, projectGroupMember.CorpId, projectGroupMember.PersonId);

        var personBankService = ServiceAccessor.GetService<PersonBankService>();

        if (person != null)
        {
            projectGroupMemberDto.PersonName = person.Name;
            projectGroupMemberDto.CardNumber = person.CardNumber;
            projectGroupMemberDto.Mobile = person.Mobile;

            var personBank = personBankService.GetDefaultPersonBankByIdCard(person.CardNumber);
            if (personBank != null)
            {
                projectGroupMemberDto.BankCardNo = personBank.CardNo ?? string.Empty;
                projectGroupMemberDto.BankName = personBank.BankName ?? string.Empty;
            }
        }
        projectGroupMemberDto.TypeName = projectGroupMember.Type?.GetDescription() ?? "";
        projectGroupMemberDto.Id = projectGroupMember.Id;
        projectGroupMemberDto.StatusName = projectGroupMember.Status.GetDescription();
        if (personCorpContracts != null)
            projectGroupMemberDto.HasContract = true;
        else projectGroupMemberDto.HasContract = false;

        return projectGroupMemberDto;
    }

    public static IEnumerable<ProjectGroupMemberDto> AsProjectGroupMemberDtos(this IEnumerable<Modules.Project.Entitys.ProjectGroupMember> projectGroupMembers)
    {
        List<ProjectGroupMemberDto> projectGroupMembersDtos = new List<ProjectGroupMemberDto>();
        foreach (var item in projectGroupMembers)
        {
            projectGroupMembersDtos.Add(item.AsProjectGroupMemberDto());
        }
        return projectGroupMembersDtos;
    }

    /// <summary>
    /// 返回考勤信息
    /// </summary>
    /// <param name="projectGroupMembers"></param>
    /// <param name="month"></param>
    /// <returns></returns>
    public static IEnumerable<ProjectGroupMemberDto> AsProjectGroupMemberCheckInDtos(this IEnumerable<Modules.Project.Entitys.ProjectGroupMember> projectGroupMembers, int month)
    {
        var projectGroupService = ServiceAccessor.GetService<ProjectGroupService>();
        var personService = ServiceAccessor.GetService<PersonService>();
        var checkInDetailService = ServiceAccessor.GetService<CheckInDetailService>();
        var checkinWorkHoursService = ServiceAccessor.GetService<CheckinWorkHoursService>();

        List<ProjectGroupMemberDto> dtos = new List<ProjectGroupMemberDto>();
        var projectGroups = projectGroupService.GetProjectGroups(projectGroupMembers.Select(i => i.GroupId));
        var persons = personService.GetPersons(projectGroupMembers.Select(i => i.PersonId));
        var checkInDetails = checkInDetailService.GetCheckinDetailsByMonthAndMemberIds(month, projectGroupMembers.Select(i => i.Id));
        var checkinWorkHours = checkinWorkHoursService.GetCheckinWorkHoursByMonthAndMemberIds(month, projectGroupMembers.Select(i => i.Id));
        foreach (var item in projectGroupMembers)
        {
            ProjectGroupMemberDto dto = new();
            dto.PersonName = persons.FirstOrDefault(i => i.PersonId == item.PersonId)?.Name ?? string.Empty;
            dto.GroupName = projectGroups.FirstOrDefault(i => i.GroupId == item.GroupId)?.Name ?? string.Empty;
            dto.CheckInDays = checkInDetails.Where(i => i.MemberId == item.Id).Select(i => i.CheckinDate.Day).Distinct();
            var checkinDate = checkinWorkHours.FirstOrDefault(i => i.MemberId == item.Id);
            dto.WorkHours = checkinDate?.WorkHours ?? 0;
            dto.CheckinDay = checkinDate?.CheckinDay ?? 0;
            dto.TypeName = item.Type?.GetDescription() ?? string.Empty;
            dto.IsManager = item.IsManager;
            dto.PostCategoryName = item.PostCategory?.GetDescription() ?? string.Empty;
            dtos.Add(dto);
        }
        return dtos;
    }
}